package com.sl.au.service.impl;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.jxls.common.Context;
import org.jxls.reader.ReaderBuilder;
import org.jxls.reader.XLSReadStatus;
import org.jxls.reader.XLSReader;
import org.jxls.util.JxlsHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import org.xml.sax.SAXException;

import com.sl.au.service.ExcelService;
import com.sl.utils.DataConverter;

@Service("excelService")
@Transactional
public class ExcelServiceImpl extends BaseServiceImpl implements ExcelService {

	private static Logger logger = LoggerFactory.getLogger(ExcelServiceImpl.class);

	@Value("${storage.location}")
	private String upload;// ="c:/upload" ;
	private String type = ".xlsx";

	@SuppressWarnings({ "unused", "unused" })
	@Override
	public <T> Path read(String entityName, Map<String, Object> collections, String... param) {
		InputStream inputXML = null;
		// 读取实体与表单映射XML文件
		try {
			inputXML = ResourceUtils.getURL("classpath:excel/" + entityName + ".xml").openStream();
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		if (null == inputXML)
			return null;
		XLSReader mainReader = null;
		try {
			mainReader = ReaderBuilder.buildFromXML(inputXML);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		}
		// 读取导入EXCEL文件
		String path = this.getStorageLocation() + "/";
		if (param.length > 0)
			path = path + param[0];
		else
			path = path + entityName + this.getType();
		URL url = null;
		try {
			url = ResourceUtils.getURL(path);
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		InputStream inputXLS = null;
		try {
			inputXLS = url.openStream();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		if (null == inputXLS)
			logger.error("找不到文件:" + path);
		List<T> list = new ArrayList<>();
		collections.put("items", list);

		try {
			XLSReadStatus readStatus = mainReader.read(inputXLS, collections);
		} catch (InvalidFormatException e) {
			e.printStackTrace();
		} catch (IOException e) {
			logger.error(e.getMessage());
		}
		System.out.println(entityName + "读取记录条数：" + list.size());
		return Paths.get(path);
	}

	@Override
	public <T> String write(List<T> list, String templateFileName, String... param) {
		String fileName = null, entityName = null;
		if (null != param && param.length > 0) {
			// 指定的目标文件名称
			fileName = param[0];
		} else {
			// 没有指定名称则自动生成
			if (!StringUtils.hasText(templateFileName))
				return null;
			String[] temp = templateFileName.split(Pattern.quote("."));
			if (temp == null)
				return null;
			entityName = temp[0];
			fileName = entityName + DataConverter.toTimeCode() + ".xlsx";

		}
		URL template = null;
		try {
			template = ResourceUtils.getURL("classpath:excel/" + templateFileName);
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		if (null == template)
			return null;
		try (InputStream is = template.openStream()) {
			if (null == is)
				logger.error("找不到模板文件：" + template);
			try (OutputStream os = new FileOutputStream(this.upload+"/"+ fileName)) {
				Context context = new Context();
				context.putVar("items", list);// 与模板中的items名称一致
				JxlsHelper.getInstance().processTemplate(is, os, context);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println(entityName + "写入记录条数：" + list.size());

		return this.upload+"/" + fileName;
	}

	@Override
	public <T> ResponseEntity<Resource> toExcel(List<T> list, String templateFileName) {
		String fileName = this.write(list, templateFileName);
		Resource file = null;
		try {
			try {
				file = new UrlResource(ResourceUtils.getURL(fileName).toURI());
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		/*
		 * if(null==a){ return ResponseEntity .notFound()
		 * .header(HttpHeaders.CONTENT_TYPE,"") .body(file); }
		 */
		String[] temp = fileName.split(Pattern.quote("/"));
		if (temp != null && temp.length > 0)
			fileName = temp[temp.length - 1];
		try {
			/*try {
				Files.delete(Paths.get(fileName));
			} catch (IOException e) {
				logger.error("删除文件失败："+fileName);
			}*/
			return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION,
					"attachment; charset=UTF-8;filename=\"" + java.net.URLEncoder.encode(fileName, "UTF-8") + "\"")
					.body(file);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public String getStorageLocation() {
		return this.upload;
	}

	@Override
	public void setStorageLocation(String location) {
		this.upload = location;

	}

	@Override
	public String getType() {
		return this.type;
	}

	@Override
	public void setType(String type) {
		this.type = type;

	}

	@Override
	public void deleteUploadFile(Path path) {
		
		try {
			Files.deleteIfExists(path);
		} catch (IOException e) {
		logger.error("删除文件失败："+e.getMessage());
		}
		
	}

	@Override
	public void importExcel(String entityName, Map<String, Object> collections, String... param) {
		Path path=this.read(entityName, collections, param);
		if(null!=path)
			this.deleteUploadFile(path);
	}

}
